package net.lab1024.sa.admin.module.business.file.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.media.Schema;
import net.lab1024.sa.admin.module.business.file.dao.DocmentaDao;
import net.lab1024.sa.admin.module.business.file.dao.DocmentaaDao;
import net.lab1024.sa.admin.module.business.file.domain.entity.DocmentPrintEntity;
import net.lab1024.sa.admin.module.business.file.domain.entity.DocmentaEntity;
import net.lab1024.sa.admin.module.business.file.domain.entity.DocmentaaEntity;
import net.lab1024.sa.admin.module.business.file.domain.form.add.DocmentaAddForm;
import net.lab1024.sa.admin.module.business.file.domain.form.query.DocmentaQueryForm;
import net.lab1024.sa.admin.module.business.file.domain.form.update.DocmentaUpdateForm;
import net.lab1024.sa.admin.module.business.file.domain.vo.DocmentaVO;
import net.lab1024.sa.admin.util.CmdExecutor;
import net.lab1024.sa.admin.util.PrintUtil;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.file.dao.FileDao;
import net.lab1024.sa.base.module.support.file.domain.vo.FileVO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPageable;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.print.*;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.OrientationRequested;
import java.awt.print.*;
import java.io.*;

import java.time.LocalDateTime;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;


@Service
public class DocmentaService {

    @Resource
    private DocmentaDao docmentaDao;
    @Resource
    private DocmentaaDao docmentaaDao;

    @Value("${file.storage.local.upload-path}")
    private String path;

    @Value("${file.storage.local.print-path}")
    private String printPath;
    @Resource
    private DocmentService docmentService;
    @Resource
    private FileDao fileDao;


    /**
     * 分页查询
     */
    public PageResult<DocmentaVO> queryPage(DocmentaQueryForm queryForm) {
        Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
        List<DocmentaVO> list = docmentaDao.queryPage(page, queryForm);
        return SmartPageUtil.convert2PageResult(page, list);
    }

    /**
     * 添加
     */

    @Transactional
    public ResponseDTO<String> add(DocmentaAddForm addForm) {
        DocmentaEntity docmentaEntity = SmartBeanUtil.copy(addForm, DocmentaEntity.class);
        docmentService.chackVersion(addForm.getDocEntry(), addForm.getBaseVersion());
        int i = docmentaDao.selectMaxLineNum(docmentaEntity.getDocEntry());
        docmentaEntity.setLineNum(++i);
        docmentaDao.insert(docmentaEntity);
        docmentService.updateVersion(addForm.getDocEntry(), addForm.getBaseVersion());
        return ResponseDTO.ok();
    }


    @Transactional
    public ResponseDTO<String> update(DocmentaUpdateForm updateForm) {

        docmentService.chackVersion(updateForm.getDocEntry(), updateForm.getBaseVersion());
        DocmentaEntity docmentaEntity = SmartBeanUtil.copy(updateForm, DocmentaEntity.class);
        docmentaEntity.setPrintApprov(false);
        if (docmentaDao.update(docmentaEntity, new LambdaQueryWrapper<DocmentaEntity>().eq(DocmentaEntity::getDocEntry, docmentaEntity.getDocEntry()).eq(DocmentaEntity::getLineNum, docmentaEntity.getLineNum())) == 0) {
            throw new RuntimeException("数据修改失败！刷新后重试");
        }
        docmentService.updateVersion(updateForm.getDocEntry(), updateForm.getBaseVersion());
        return ResponseDTO.ok();


    }

    public ResponseDTO<String> batchDelete(List<Long> idList) {

        docmentaDao.deleteBatchIds(idList);
        return ResponseDTO.ok();
    }

    public ResponseDTO<String> delete(Long docEntry) {
        docmentaDao.deleteById(docEntry);
        return ResponseDTO.ok();
    }


    @Transactional
    public ResponseDTO<String> print(DocmentaQueryForm queryForm) throws Exception{
        docmentService.chackVersion(queryForm.getDocEntry(), queryForm.getBaseVersion());

        Integer i = docmentaaDao.selectMaxLineNum(queryForm.getDocEntry());

        DocmentaaEntity docmentaaEntity = docmentaaDao.selectOne(new LambdaQueryWrapper<DocmentaaEntity>().eq(DocmentaaEntity::getDocEntry, queryForm.getDocEntry()).eq(DocmentaaEntity::getLineNum, i));
        ResponseDTO responseDTO=CmdExecutor.printFile(printPath + queryForm.getDocKey(),queryForm.getMacName(), docmentaaEntity.getPrintNum());
        //PrintUtil.print(path + queryForm.getDocKey(),queryForm.getMacName(), docmentaaEntity.getPrintNum());
        if(Objects.equals(10001,responseDTO.getCode())){
            return  responseDTO;
        }
        Integer i1 = docmentaDao.selectMaxLineNum(queryForm.getDocEntry());

        DocmentaEntity docmentaEntity = docmentaDao.selectOne(new LambdaQueryWrapper<DocmentaEntity>().eq(DocmentaEntity::getDocEntry, queryForm.getDocEntry()).eq(DocmentaEntity::getLineNum, i1));

        docmentaEntity.setPrintNum(docmentaEntity.getPrintNum() + docmentaaEntity.getPrintNum());

        docmentaEntity.setPrintApprov(false);




        docmentaDao.update(docmentaEntity, new LambdaQueryWrapper<DocmentaEntity>().eq(DocmentaEntity::getDocEntry, queryForm.getDocEntry()).eq(DocmentaEntity::getLineNum, i1));

        docmentService.updateVersion(queryForm.getDocEntry(), queryForm.getBaseVersion());

        return ResponseDTO.ok();
    }


    /**
     * 打印文件
     * @param filePath 本地文件路径
     * @param printerName 打印机名称
     * @param copies 打印份数
     * @return 打印是否成功
     */
    public ResponseDTO<String> printFile(String filePath, String printerName, int copies) {

        CmdExecutor.printFile(filePath,printerName,copies);
        // 验证参数
        if (filePath == null || filePath.isEmpty()) {
            System.err.println("文件路径不能为空");
        }

        if (printerName == null || printerName.isEmpty()) {
            System.err.println("打印机名称不能为空");
        }

        if (copies <= 0) {
            System.err.println("打印份数必须大于0");
        }

        File file = new File(filePath);
        if (!file.exists() || !file.isFile()) {
            System.err.println("文件不存在或不是一个有效的文件: " + filePath);
        }

        try (InputStream inputStream = new FileInputStream(file)) {
            // 获取文档的 mime 类型
            String mimeType = getMimeType(file);

            // 创建打印请求属性集
            PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
            // 设置打印份数
            attributes.add(new Copies(copies));
            // 设置打印方向为纵向
            attributes.add(OrientationRequested.PORTRAIT);

            // 查找所有可用的打印机
            PrintService[] printServices = PrinterJob.lookupPrintServices();
            if (printServices == null || printServices.length == 0) {
                System.err.println("没有找到可用的打印机");
            }


            // 查找指定名称的打印机
            PrintService printService = null;
            for (PrintService service : printServices) {
                if (service.getName().equals(printerName)) {
                    printService = service;
                    break;
                }
            }

            if (printService == null) {
                System.err.println("未找到名称为 '" + printerName + "' 的打印机");
                System.out.println("可用的打印机列表:");
                for (PrintService service : printServices) {
                    System.out.println("- " + service.getName());
                }
            }

            // 创建要打印的文档
            Doc doc = new SimpleDoc(inputStream, DocFlavor.INPUT_STREAM.AUTOSENSE, null);

            // 创建打印作业
            DocPrintJob printJob = printService.createPrintJob();

            // 执行打印
            printJob.print(doc, attributes);
            System.out.println("打印任务已提交到打印机: " + printerName +
                    ", 文件名: " + file.getName() + ", 份数: " + copies);

        } catch (Exception e) {
            System.err.println("打印过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
        return ResponseDTO.ok();
    }

    /**
     * 获取文件的MIME类型
     */
    private String getMimeType(File file) {
        String fileName = file.getName();
        if (fileName.endsWith(".txt")) {
            return "text/plain";
        } else if (fileName.endsWith(".pdf")) {
            return "application/pdf";
        } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (fileName.endsWith(".png")) {
            return "image/png";
        } else if (fileName.endsWith(".gif")) {
            return "image/gif";
        } else if (fileName.endsWith(".doc") || fileName.endsWith(".docx")) {
            return "application/msword";
        } else if (fileName.endsWith(".xls") || fileName.endsWith(".xlsx")) {
            return "application/vnd.ms-excel";
        } else {
            return "application/octet-stream";
        }
    }




    public ResponseDTO<PrintService[]> macList() {
        PrintService[] printServices = PrinterJob.lookupPrintServices();
        return ResponseDTO.ok(printServices);
    }

    public ResponseDTO<Set<String>> printlist() {
        LinkedHashSet<String> strings = new LinkedHashSet<>();
        for (PrintService printService : PrinterJob.lookupPrintServices()) {
            strings.add(printService.getName());
        }
        return ResponseDTO.ok(strings);
    }

    public ResponseDTO<String> printNoRole(DocmentaQueryForm queryForm) {

        String[] wpsProcesses = {"wps.exe", "wpspdf.exe", "et.exe", "wpp.exe","wpscloudsvr.exe"};
        for (String process : wpsProcesses) {
            closeProcess(process);
        }

        FileVO fileVo = fileDao.getByFileKey(queryForm.getFileKey());
        //打印文件
        for(int i = 0; i < queryForm.getCopies(); i++) {
            ResponseDTO responseDTO=CmdExecutor.printFile(printPath + queryForm.getFileKey(),queryForm.getPrinterId(), queryForm.getCopies());
            if(Objects.equals(10001,responseDTO.getCode())){
                return  responseDTO;
            }
            try {
                Thread.sleep(10000);
                // WPS相关进程名称数组
                for (String process : wpsProcesses) {
                    closeProcess(process);
                }
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        //查询打印信息
        RequestUser requestUser = SmartRequestUtil.getRequestUser();
        queryForm.setCreateById(requestUser.getUserId());
        queryForm.setCreateBy(requestUser.getUserName());
        queryForm.setCreateTime(LocalDateTime.now());
        queryForm.setCreateIp(requestUser.getIp());
        queryForm.setFileName(fileVo.getFileName());
        queryForm.setFileSize(fileVo.getFileSize());
        queryForm.setFileType(fileVo.getFileType());
        //记录打印文件历史
        docmentaDao.insertPrint(queryForm);
        return ResponseDTO.ok();
    }


    /**
     * 关闭指定名称的进程
     * @param processName 进程名称
     */
    private static void closeProcess(String processName) {
        CmdExecutor.executeWindowsCommand("taskkill /F /IM " + processName);
//        try {
//            // 执行taskkill命令关闭进程 /F表示强制关闭 /IM指定进程名称
//            Process process = Runtime.getRuntime().exec("taskkill /F /IM " + processName);
//
//
//            // 等待命令执行完成
//            int exitCode = process.waitFor();
//
//            // 读取命令输出
//            BufferedReader reader = new BufferedReader(
//                    new InputStreamReader(process.getInputStream(), "GBK")); // 使用GBK编码适配Windows
//            String line;
//            StringBuilder output = new StringBuilder();
//            while ((line = reader.readLine()) != null) {
//                output.append(line).append("\n");
//            }
//
//            if (exitCode == 0) {
//                System.out.println("成功关闭进程: " + processName);
//                System.out.println("输出信息: " + output.toString());
//            } else {
//                System.out.println("关闭进程失败或进程未运行: " + processName);
//                System.out.println("错误信息: " + output.toString());
//            }
//
//        } catch (IOException | InterruptedException e) {
//            System.err.println("操作进程时发生错误: " + e.getMessage());
//            e.printStackTrace();
//        }
    }

    public PageResult<DocmentPrintEntity> selectPrint(DocmentaQueryForm queryForm) {
        Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
        List<DocmentPrintEntity> list = docmentaDao.queryPagePrint(page, queryForm.getCreateBy(),queryForm.getFileName(),printPath);
        return SmartPageUtil.convert2PageResult(page, list);
    }
}
